package com.lse_api.control;


import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lse_api.entity.*;
import com.lse_api.service.*;
import com.lse_api.utils.DateUtil;
import com.lse_api.utils.PageUtil;
import com.lse_api.utils.ReturnMsg;
import com.lse_api.utils.Status;
import com.lse_api.utils.encryption.AESEncryption;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.stereotype.Controller;
import com.lse_api.exception.LseException;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 项目组 前端控制器
 * </p>
 *
 * @author 祁雪
 * @since 2020-05-11
 */
@Slf4j
@Controller
@RequestMapping("/lseapi/api/groups")
public class GroupListController extends LseException implements ReturnMsg {

    @Autowired
    private GroupListService groupListService;

    @Autowired
    private GroupUserService groupUserService;

    @Autowired
    private GroupProjectService groupProjectService;

    @Autowired
    private GroupUserAuditService groupUserAuditService;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private HttpServletRequest request;

    /**
     * 创建项目组
     *
     * @param groups
     * @return
     */
    @RequestMapping(value = "/createGroup")
    @ResponseBody
    public Status createGroup(GroupList groups) {

        if (StringUtils.isEmpty(groups.getGroupName())) {
            return Status.error(API_GROUP_NAME);
        }

        Token token = (Token) request.getAttribute("token");
        groups.setCreateTime(new Date());
        groups.setGroupCreate(token.getUsersUid());

        boolean flag = groupListService.save(groups);
        if (flag) {

            // 录入组成员
            GroupUser groupUser = new GroupUser();
            groupUser.setGroupId(groups.getId());
            groupUser.setIsCreate(1);
            groupUser.setJoinTime(new Date());
            groupUser.setUserId(token.getUsersUid());

            groupUserService.save(groupUser);
        }

        return flag ? Status.success(CREATE_SUCCESS) : Status.error(CREATE_FAILURE);

    }

    /**
     * 解散项目组
     * group: 项目组id
     *
     * @return
     */
    @RequestMapping(value = "/dissolveGroup")
    @ResponseBody
    public Status dissolveGroup() {

        String group = request.getParameter("group");

        if (StringUtils.isEmpty(group)) {
            return Status.error(API_GROUP_ID);
        }

        Token token = (Token) request.getAttribute("token");
        // 判断项目组是否由登录者创建
        QueryWrapper<GroupList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", group)
                .eq("group_create", token.getUsersUid());

        GroupList groups = groupListService.getOne(queryWrapper);

        if (groups == null) {
            return Status.error(API_GROUP_NOT_ME);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("group_id", groups.getId());
        // 清除项目组内成员申请
        groupUserAuditService.removeByMap(map);
        // 清除项目组内成员关联
        groupUserService.removeByMap(map);
        // 清除项目组内项目关联
        groupProjectService.removeByMap(map);

        boolean flag = groupListService.remove(queryWrapper);

        return flag ? Status.success(DELETESUCCESS) : Status.error(DELETEFAILURE);
    }

    /**
     * 项目迁移至项目组
     * group: 项目组ID
     * project: 项目ID
     *
     * @return
     */
    @RequestMapping(value = "/projectToGroup")
    @ResponseBody
    public Status projectToGroup() {

        String groupId = request.getParameter("group");

        String projectId = request.getParameter("project");

        if (StringUtils.isEmpty(groupId)) {
            return Status.error(API_GROUP_ID);
        }

        if (StringUtils.isEmpty(projectId)) {
            return Status.error(API_PROJECT_ID);
        }

        // 检查项目组是否存在
        /*QueryWrapper<Groups> groupsQueryWrapper = new QueryWrapper<>();
        groupsQueryWrapper.eq("id", groupId);
        int count = groupListService.count(groupsQueryWrapper);
        if (count == 0) {
            return Status.error(API_GROUP_NULL);
        }*/

        Token token = (Token) request.getAttribute("token");

        // 检查项目是否已经迁移
        QueryWrapper<GroupProject> groupProjectQueryWrapper = new QueryWrapper<>();
        groupProjectQueryWrapper.eq("project_id", projectId);
        int count = groupProjectService.count(groupProjectQueryWrapper);
        if (count > 0) {
            return Status.error(API_GROUP_PROJECT_HAVING);
        }

        // 检查是否已存在于该项目组
        QueryWrapper<GroupUser> groupUserQueryWrapper = new QueryWrapper<>();
        groupUserQueryWrapper.eq("group_id", groupId)
                .eq("user_id", token.getUsersUid());

        count = groupUserService.count(groupUserQueryWrapper);

        if (count == 0) {
            return Status.error(API_GROUP_USER_NOT_EX);
        }

        // 检查是否是登录者创建的项目
        QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", projectId)
                .eq("project_create", token.getUsersUid());

        count = projectService.count(queryWrapper);

        if (count == 0) {
            return Status.error(API_PROJECT_NOT_ME);
        }

        GroupProject groupProject = new GroupProject();
        groupProject.setCreateTime(new Date());
        groupProject.setGroupId(Integer.parseInt(groupId));
        groupProject.setProjectId(Integer.parseInt(projectId));

        boolean flag = groupProjectService.save(groupProject);

        return flag ? Status.success(API_PROJECT_TO_SUCCESS) : Status.error(API_PROJECT_TO_FAILURE);
    }

    /**
     * 审批项目组成员申请
     * audit: 审批记录ID
     * join: 1.同意 2.拒绝
     *
     * @return
     */
    @RequestMapping(value = "/updateGroupUserAudit")
    @ResponseBody
    public Status updateGroupUserAudit() {

        String auditId = request.getParameter("audit");

        String isJoin = request.getParameter("join");

        if (StringUtils.isEmpty(auditId)) {
            return Status.error(API_GROUP_USER_AUDIT_ID);
        }

        if (!NumberUtil.isInteger(isJoin)) {
            return Status.error(NUMBER_IS_NOT);
        }

        GroupUserAudit groupUserAudit = groupUserAuditService.getById(auditId);

        if (groupUserAudit == null) {
            return Status.error(API_GROUP_USER_AUDIT_NULL);
        }

        Token token = (Token) request.getAttribute("token");

        // 查询该项目组是否由已登录者创建
        QueryWrapper<GroupList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", groupUserAudit.getGroupId())
                .eq("group_create", token.getUsersUid());

        int count = groupListService.count(queryWrapper);

        if (count == 0) {
            return Status.error(API_GROUP_NOT_ME);
        }

        if (Integer.parseInt(isJoin) == 1) {
            groupUserAudit.setIsJoin(1);
            // 录入组成员
            GroupUser groupUser = new GroupUser();
            groupUser.setGroupId(groupUserAudit.getGroupId());
            groupUser.setIsCreate(0);
            groupUser.setJoinTime(new Date());
            groupUser.setUserId(groupUserAudit.getUserId());

            boolean flag = groupUserService.save(groupUser);
            // 修改审批记录
            if (flag) {
                groupUserAuditService.updateById(groupUserAudit);
            }

            return flag ? Status.success(UPDATESUCCESS) : Status.error(UPDATEFAILURE);

        } else {
            groupUserAudit.setIsJoin(2);
            boolean flag = groupUserAuditService.updateById(groupUserAudit);
            return flag ? Status.success(UPDATESUCCESS) : Status.error(UPDATEFAILURE);
        }

    }

    /**
     * 发送审批记录
     * 注: 该接口由前端自动生成连接由用户点击跳转新的页面(未登录提示登录) 由页面读取token Ajax提交接口
     *
     * @param groupUserAudit
     * @return
     */
    @RequestMapping(value = "/sendGroupAudit")
    @ResponseBody
    public Status sendGroupAudit(GroupUserAudit groupUserAudit) {

        if (StringUtils.isEmpty(groupUserAudit.getGroupId())) {
            return Status.error(API_GROUP_ID);
        }
        groupUserAudit.setIsJoin(0);
        groupUserAudit.setCreateTime(new Date());

        Token token = (Token) request.getAttribute("token");

        groupUserAudit.setUserId(token.getUsersUid());
        // 检查是否发送过未处理审批记录
        QueryWrapper<GroupUserAudit> groupUserAuditQueryWrapper = new QueryWrapper<>();
        groupUserAuditQueryWrapper.eq("group_id", groupUserAudit.getGroupId())
                .eq("user_id", token.getUsersUid())
                .eq("is_join", 0);

        int count = groupUserAuditService.count(groupUserAuditQueryWrapper);

        if (count != 0) {
            return Status.error(API_GROUP_USER_AUDIT_REPEAT);
        }

        // 判断用户是否已存在项目组内
        QueryWrapper<GroupUser> groupUserQueryWrapper = new QueryWrapper<>();
        groupUserQueryWrapper.eq("group_id", groupUserAudit.getGroupId())
                .eq("user_id", token.getUsersUid());

        count = groupUserService.count(groupUserQueryWrapper);
        if (count != 0) {
            return Status.error(API_GROUP_USER_IS_HAVE);
        }

        // 判定邀请人是否为该项目组创建者
        if (!StringUtils.isEmpty(groupUserAudit.getInviter())) {
            QueryWrapper<GroupList> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("id", groupUserAudit.getGroupId())
                    .eq("group_create", groupUserAudit.getInviter());

            count = groupListService.count(queryWrapper);

            if (count != 0) {
                // 直接加入项目组
                // 录入组成员
                GroupUser groupUser = new GroupUser();
                groupUser.setGroupId(groupUserAudit.getGroupId());
                groupUser.setIsCreate(0);
                groupUser.setJoinTime(new Date());
                groupUser.setUserId(groupUserAudit.getUserId());

                boolean flag = groupUserService.save(groupUser);
                return flag ? Status.success(API_GROUP_USER_AUDIT_OK) : Status.error(SENDFAILURE);
            }

        }

        boolean flag = groupUserAuditService.save(groupUserAudit);

        return flag ? Status.success(SENDSUCCESS) : Status.error(SENDFAILURE);

    }

    /**
     * T出项目组成员
     * group: 项目组ID
     * user: 用户ID
     *
     * @return
     */
    @RequestMapping(value = "/kickGroupUser")
    @ResponseBody
    public Status kickGroupUser() {
        Token token = (Token) request.getAttribute("token");

        String groupId = request.getParameter("group");

        String userId = request.getParameter("user");

        if (StringUtils.isEmpty(groupId)) {
            return Status.error(API_GROUP_ID);
        }

        if (StringUtils.isEmpty(userId)) {
            return Status.error(API_GROUP_USER_ID);
        }

        // 判断被T者是否是登录者
        if (userId.equalsIgnoreCase(token.getUsersUid())) {
            return Status.error(API_GROUP_USER_ME);
        }
        // 检查登录者是否是项目组创建者

        QueryWrapper<GroupList> groupsQueryWrapper = new QueryWrapper<>();
        groupsQueryWrapper.eq("id", groupId)
                .eq("group_create", token.getUsersUid());

        int count = groupListService.count(groupsQueryWrapper);

        if (count == 0) {
            return Status.error(API_GROUP_NOT_ME);
        }

        // 清除此记录
        Map<String, Object> map = new HashMap<>();
        map.put("group_id", groupId);
        map.put("user_id", userId);

        boolean flag = groupUserService.removeByMap(map);

        if (flag) {
            // 迁出组内用户创建的项目
            groupUserService.removeByGroupAndUser(userId, groupId);
        }

        return flag ? Status.success(DELETESUCCESS) : Status.error(DELETEFAILURE);
    }

    /**
     * 项目移出项目组
     * 注: 移出项目仅能项目创建者操作
     *
     * @param groupProject
     * @return
     */
    @RequestMapping(value = "/projectOutGroup")
    @ResponseBody
    public Status projectOutGroup(GroupProject groupProject) {

        if (StringUtils.isEmpty(groupProject.getGroupId())) {
            return Status.error(API_GROUP_ID);
        }

        if (StringUtils.isEmpty(groupProject.getProjectId())) {
            return Status.error(API_PROJECT_ID);
        }

        Token token = (Token) request.getAttribute("token");
        // 判定项目是否是已登录用户创建
        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        projectQueryWrapper.eq("id", groupProject.getProjectId())
                .eq("project_create", token.getUsersUid());

        int count = projectService.count(projectQueryWrapper);

        if (count == 0) {
            return Status.error(API_PROJECT_NOT_ME);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("group_id", groupProject.getGroupId());
        map.put("project_id", groupProject.getProjectId());

        boolean flag = groupProjectService.removeByMap(map);

        return flag ? Status.success(API_PROJECT_TO_SUCCESS) : Status.error(API_PROJECT_TO_FAILURE);

    }

    /**
     * 读取项目组列表 - 创建的
     * pageNo: 页码
     * pageSize: 每页数量
     *
     * @return
     */
    @RequestMapping(value = "/getGroupListByMe")
    @ResponseBody
    public Status getGroupListByMe() {
        String pageNo = request.getParameter("pageNo");
        String pageSize = request.getParameter("pageSize");

        Map<String, Integer> map = PageUtil.getPage(pageNo, pageSize);

        Token token = (Token) request.getAttribute("token");

        QueryWrapper<GroupList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("group_create", token.getUsersUid());
        PageHelper.startPage(map.get("pageNo"), map.get("pageSize"));

        List<GroupList> list = groupListService.list(queryWrapper);

        PageInfo<GroupList> pageInfo = new PageInfo<>(list);

        return Status.success(pageInfo);
    }

    /**
     * 读取项目组列表 - 加入的
     * pageNo: 页码
     * pageSize: 每页数量
     *
     * @return
     */
    @RequestMapping(value = "/getGroupListByJoin")
    @ResponseBody
    public Status getGroupListByJoin() {

        String pageNo = request.getParameter("pageNo");
        String pageSize = request.getParameter("pageSize");

        Map<String, Integer> map = PageUtil.getPage(pageNo, pageSize);

        Token token = (Token) request.getAttribute("token");

        PageHelper.startPage(map.get("pageNo"), map.get("pageSize"));

        List<GroupList> list = groupListService.getGroupListByJoin(token.getUsersUid());

        PageInfo<GroupList> pageInfo = new PageInfo<>(list);

        return Status.success(pageInfo);
    }

    /**
     * 获取项目组加密ID - 用于精确查找
     * group: 项目组ID
     *
     * @return
     */
    @RequestMapping(value = "/getGroupSale")
    @ResponseBody
    public Status getGroupSale() {

        String groupId = request.getParameter("group");

        if (StringUtils.isEmpty(groupId)) {
            return Status.error(API_GROUP_ID);
        }

        return Status.success(API_GROUP_ID_SALE,
                AESEncryption.Ecodes(groupId, "LSE" + DateUtil.getOneDateTime(new Date(), "yyyy-MM-dd HH")));

    }

    /**
     * 精确查找项目组 - 用于搜索精确查找全部项目组 传入加密密钥(ID加密)
     * group: 群组加密密钥
     *
     * @return
     */
    @RequestMapping(value = "/findGroup")
    @ResponseBody
    public Status findGroup() {

        try {
            String groupKey = request.getParameter("group");

            if (StringUtils.isEmpty(groupKey)) {
                return Status.error(API_GROUP_FIND_ID);
            }

            String groupId = AESEncryption.Dcodes(groupKey, "LSE" + DateUtil.getOneDateTime(new Date(), "yyyy-MM-dd HH"));

            if (StringUtils.isEmpty(groupId)) {
                return Status.error(KEY_ERROR);
            }

            GroupList groups = groupListService.getById(groupId);

            return groups != null ? Status.success(groups) : Status.error(API_GROUP_NULL);

        } catch (Exception e) {
            log.error(KEY_ERROR, e);
            return Status.error(KEY_ERROR);
        }

    }

    /**
     * 项目组内项目以及项目创建者
     * group: 项目组ID
     *
     * @return
     */
    @RequestMapping(value = "/getProjectListByGroup")
    @ResponseBody
    public Status getProjectListByGroup() {

        String groupId = request.getParameter("group");

        if (StringUtils.isEmpty(groupId)) {
            return Status.error(API_GROUP_ID);
        }

        List<Project> list = projectService.getProjectListByGroup(groupId);

        return Status.success(list);

    }

    /**
     * 项目组内成员
     * group: 项目组ID
     * pageNo: 页码
     * pageSize: 每页数量
     *
     * @return
     */
    @RequestMapping(value = "/getUserListByGroup")
    @ResponseBody
    public Status getUserListByGroup() {
        String groupId = request.getParameter("group");
        String pageNo = request.getParameter("pageNo");
        String pageSize = request.getParameter("pageSize");

        if (StringUtils.isEmpty(groupId)) {
            return Status.error(API_GROUP_ID);
        }

        Map<String, Integer> map = PageUtil.getPage(pageNo, pageSize);

        PageHelper.startPage(map.get("pageNo"), map.get("pageSize"));

        List<GroupUser> list = groupUserService.getUserListByGroup(groupId);

        PageInfo<GroupUser> pageInfo = new PageInfo<>(list);

        return Status.success(pageInfo);

    }

    /**
     * 项目组成员邀请者信息
     * 用于项目组审批时管理者查询用户由谁邀请
     * inviter: 邀请者用户ID
     *
     * @return
     */
    @RequestMapping(value = "/getInviterInfo")
    @ResponseBody
    public Status getInviterInfo() {

        String inviter = request.getParameter("inviter");

        if (StringUtils.isEmpty(inviter)) {
            return Status.error(API_GROUP_INVITER);
        }

        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("users_uid", inviter);

        UserInfo userInfo = userInfoService.getOne(queryWrapper);

        return userInfo != null ? Status.success(userInfo) : Status.error(USERINFO_NULL);

    }

    /**
     * 项目组成员申请列表 - 只能由项目组创建者读取
     * group: 项目组ID
     * pageNo: 页码
     * pageSize: 每页数量
     *
     * @return
     */
    @RequestMapping(value = "/getAuditListByGroup")
    @ResponseBody
    public Status getAuditListByGroup() {

        String groupId = request.getParameter("group");
        String pageNo = request.getParameter("pageNo");
        String pageSize = request.getParameter("pageSize");

        if (StringUtils.isEmpty(groupId)) {
            return Status.error(API_GROUP_ID);
        }
        // 判定用户是否为该群组创建者
        Token token = (Token) request.getAttribute("token");
        QueryWrapper<GroupList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", groupId)
                .eq("group_create", token.getUsersUid());
        int count = groupListService.count(queryWrapper);

        if (count == 0) {
            return Status.error(API_GROUP_NOT_ME);
        }

        Map<String, Integer> map = PageUtil.getPage(pageNo, pageSize);

        PageHelper.startPage(map.get("pageNo"), map.get("pageSize"));

        List<GroupUserAudit> list = groupUserAuditService.getAuditListByGroup(groupId);

        PageInfo<GroupUserAudit> pageInfo = new PageInfo<>(list);

        return Status.success(pageInfo);
    }

    /**
     * 获取项目组分享外链KEY
     * group: 项目组ID
     *
     * @return
     */
    @RequestMapping(value = "/getGroupShareKey")
    @ResponseBody
    public Status getGroupShareKey() {

        Token token = (Token) request.getAttribute("token");

        String groupId = request.getParameter("group");

        if (StringUtils.isEmpty(groupId)) {
            return Status.error(groupId);
        }

        String data = AESEncryption.Ecodes(groupId + "_" + token.getUsersUid(), "LSE" + DateUtil.getOneDateTime(new Date(), "yyyy-MM-dd HH"));

        return Status.success("the key create success", data);

    }

}

